package com.hyt.it.ogt.ks.service.Event;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

import javax.annotation.Resource;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.hyt.it.ogt.ks.config.ConfigManager;
import com.hyt.it.ogt.ks.model.entity.mongodb.CandidateAnswerLogBackup;
import com.hyt.it.ogt.ks.model.vo.CandidateQusAnsVO;
import com.hyt.it.ogt.ks.mq.model.CandidateAnswerLogBackupDTO;
import com.hyt.it.ogt.ks.service.CandidateAnswerLogService;

import lombok.extern.slf4j.Slf4j;

/**
 * @author wuyingge
 * @ClassName CandidateAnswerLogListener.java
 * @Description 考生保存答案请求参数日志事件
 * @createTime 2021年10月23日 17:21:00
 */
@Component
@Slf4j
public class CandidateAnswerLogListener implements ApplicationListener<CandidateAnswerLogEvent> , DisposableBean {

    private final List<CandidateQusAnsVO> answerLogs = new ArrayList<>();

    private final List<CandidateAnswerLogBackup> backupLogs = new ArrayList<>();

    private final AtomicInteger answerSize = new AtomicInteger(0);

    private final AtomicInteger backSize = new AtomicInteger(0);

    private final ReentrantLock lock = new ReentrantLock(true);

    @Resource
    private CandidateAnswerLogService candidateAnswerLogService;
    @Resource
    private ConfigManager configManager;

    @Override
    @Async
    public void onApplicationEvent(CandidateAnswerLogEvent event) {
        Integer timeConsumer = event.getTimeConsumer();
        if(Objects.nonNull(timeConsumer)){
            timeToConsumer();
            return;
        }
        CandidateQusAnsVO answerLog = event.getAnswerLog();
        CandidateAnswerLogBackup answerBackup = event.getAnswerBackup();
        if(Objects.isNull(answerLog) && Objects.isNull(answerBackup)){
            log.error("收到考生保存答案请求参数日志事件，收到数据为空!");
            return;
        }
        log.debug("收到考生保存答案请求参数日志事件，收到数据为:{}",event);
        putLogToList(answerLog,answerBackup);
    }

    private void putLogToList(CandidateQusAnsVO answerLog, CandidateAnswerLogBackup answerBackup){
        try {
            lock.lock();
            if(Objects.nonNull(answerLog)){
                answerLogs.add(answerLog);
                answerSize.addAndGet(1);
            }
            if(Objects.nonNull(answerBackup)){
                backupLogs.add(answerBackup);
                backSize.addAndGet(1);
            }
            if(configManager.getCandidateAnswerLogCapacity() <= answerSize.get()){
                CandidateAnswerLogBackupDTO msg =
                        CandidateAnswerLogBackupDTO.builder().answerBackups(backupLogs).answerLogs(answerLogs).build();
                log.info("发送考生日志备份文件，log条数为:{},backup条数为:{}",answerSize.get(),backSize.get());
                candidateAnswerLogService.consumerLog(msg);
                answerLogs.clear();
                backupLogs.clear();
                answerSize.set(0);
                backSize.set(0);
            }
        } finally {
            lock.unlock();
        }
    }

    private void timeToConsumer(){
        log.info("考生答案备份定时任务启动成功");
        try {
            lock.lock();
            if(answerSize.get() > 0 || backSize.get() > 0){
                log.info("-----发送考生日志备份文件，log条数为:{},backup条数为:{}",answerSize.get(),backSize.get());
                CandidateAnswerLogBackupDTO msg =
                        CandidateAnswerLogBackupDTO.builder().answerBackups(backupLogs).answerLogs(answerLogs).build();
                candidateAnswerLogService.consumerLog(msg);
                answerLogs.clear();
                backupLogs.clear();
                answerSize.set(0);
                backSize.set(0);
            }
        } finally {
            lock.unlock();
        }
        log.info("考生答案备份定时任务处理完成");
    }


    @Override
    public void destroy() throws Exception {
        if(answerSize.get() > 0 || backSize.get() > 0){
            log.info("发送考生日志备份文件，log条数为:{},backup条数为:{}",answerSize.get(),backSize.get());
            CandidateAnswerLogBackupDTO msg =
                    CandidateAnswerLogBackupDTO.builder().answerBackups(backupLogs).answerLogs(answerLogs).build();
            candidateAnswerLogService.consumerLog(msg);
            answerLogs.clear();
            backupLogs.clear();
            answerSize.set(0);
        }
    }
}
